<template>
    <div class="mb-wrap" v-loading="loading">
        <div class="apps-menu-actions">
            <div class="apps-menu-actionitem none" @click="handleShowCreateGroupRoot">
                <i class="el-icon-plus"></i> &nbsp;分组
            </div>
            <div class="apps-menu-actionitem none" @click="handleShowCreateMenuRoot"
                 style="border-left: 1px solid #F1F1F1;">
                <i class="el-icon-plus"></i> &nbsp;菜单
            </div>
        </div>
        <el-input v-model="queryText" size="mini" class="thin-search-input" clearable placeholder="按名称搜索"></el-input>
        <perfect-scrollbar class="mb-tree" :settings="{}" @click="handleClearSelect()">
            <el-tree ref="menutree"
                     class="menu-custom-tree"
                     :data="items"
                     node-key="tid"
                     :highlight-current="true"
                     :expand-on-click-node="false"
                     :default-expanded-keys="expandedKeys"
                     :props="treeSetting"
                     :filter-node-method="filterNode"
                     draggable
                     @node-drop="handleDragDrop"
                     @click.native.stop="empty"
                     @node-click="handleClick">
                <span class="menu-custom-tree-node menu-icon-node" slot-scope="{ node, data }">
                    <span class="menu-custom-icon" :class="{ 'is-app': isApp(data), 'is-empty': isGroup(data) }"
                          :style="getIconStyle(data)">
                        <i v-if="data.loading" class="el-icon-loading"></i>
                        <img v-else-if="isGroup(data)" :src="getIconDefault(data)" />
                        <img v-else-if="getIconImg(data)" :src="getIconImg(data)" />
                        <!--<i v-else-if="getIconFont(data)" :class="getIconFont(data)"></i>-->
                        <template v-else-if="getNodeIconFont(data)">
                            <i class="menu-icon-white" :class="getNodeIconFont(data)"></i>
                            <i class="menu-icon-color" :class="getNodeIconFont(data)"></i>
                        </template>
                        <img v-else :src="getIconDefault(data)" />
                    </span>
                    <span>{{ getNodeName(data) }}</span>
                    <i v-if="isApp(data)" class="app-icon fa fa-app-store" v-tippy="{ arrow: true }" content="应用"></i>
                    <i v-if="isWhite(data, 1)" class="app-icon fa fa-wikipedia-w" v-tippy="{ arrow: true }" content="白名单（仅菜单）" style="transform:scale(.6)"></i>
                    <i v-if="isWhite(data, 2)" class="app-icon fa fa-weebly" v-tippy="{ arrow: true }" content="白名单（菜单 & 数据）" style="transform:scale(.8)"></i>
                    <i slot="reference" class="el-icon-more btn-more" @click.stop="showNodeMorePopover($event,data)"></i>
                </span>
            </el-tree>
        </perfect-scrollbar>
        <!--</div>-->
        <el-popover ref="nodeMorePopover" popper-class="popover-dropdown-menu el-dropdown-menu--small" placement="right-start" trigger="click">
            <ul>
                <template v-if="!isMenu(popData)">
                    <li class="el-dropdown-menu__item" @click="handleShowCreateGroup"><i class="el-icon-plus"></i>分组</li>
                    <li class="el-dropdown-menu__item" @click="handleShowCreateMenu"><i class="el-icon-plus"></i>菜单</li>
                </template>
                <li class="el-dropdown-menu__item" :class="{
                    'el-dropdown-menu__item--divided': !isMenu(popData)
                }" @click="handleShowEdit"><i class="el-icon-edit"></i>修改</li>
                <li @click="handleRemoveShow" class="el-dropdown-menu__item"><i class="el-icon-delete"></i>删除</li>
            </ul>
        </el-popover>

        <el-dialog :title="menuFormWinName" :visible.sync="menuFormShow" top="40px" custom-class="m-dialog-style"
                   :close-on-click-modal="false" :append-to-body="true">
            <div style="padding: 10px 30px 5px;background: #FFF;">
                <form-group v-if="isGroupForm(popData)" :action-type="actionType" :current-data="popData" :tty="tty" :menutree="items"
                            :app-id="appId" @success="handleSuccess" @cancel="handleCancel"></form-group>
                <form-menu v-else-if="isMenuForm(popData)" :action-type="actionType" :current-data="popData" :tty="tty" :menutree="items"
                           :app-id="appId" @success="handleSuccess" @cancel="handleCancel"></form-menu>
                <form-app v-else-if="isAppForm(popData)" :action-type="actionType" :current-data="popData" :tty="tty" :menutree="items"
                          :app-id="appId" @success="handleSuccess" @cancel="handleCancel"></form-app>
            </div>
        </el-dialog>

        <div class="mb-info">
            <div class="actions" v-if="canEdit">
                <el-button size="mini" icon="el-icon-plus" type="primary" :disabled="currentData && currentData.id && !_isGroup(currentData)"
                           @click="handleShowCreateGroup()">分组 </el-button>
                <el-button size="mini" icon="el-icon-plus" type="primary" :disabled="isMenu(currentData)"
                           v-if="tty == 9"
                           @click="handleShowCreatePermission()">权限 </el-button>
                <el-button size="mini" icon="el-icon-plus" type="primary" :disabled="isMenu(currentData) || isApp(currentData)"
                           v-if="tty != 9"
                           @click="handleShowCreateApp()">应用 </el-button>
                <el-button size="mini" icon="el-icon-plus" type="primary" :disabled="isMenu(currentData)"
                           v-if="tty != 9"
                           @click="handleShowCreateMenu()">菜单 </el-button>
                <el-button size="mini" icon="el-icon-edit-outline" type="primary"
                           @click="handleShowEdit()" :disabled="!isSelected(currentData)">修改 </el-button><!-- :disabled="!isGroup(currentData) && !isMenu(currentData)" -->
                <el-button size="mini" icon="el-icon-delete" type="primary"
                           @click="handleShowDelete(currentData)" :disabled="!isSelected(currentData)">删除 </el-button><!-- !isGroup(currentData) && !isMenu(currentData) -->
            </div>
            <div class="info">
                <form-group v-if="isGroupForm(currentData)" :action-type="actionType" :current-data="currentData" :tty="tty" :menutree="items"
                            @success="handleSuccess" @cancel="handleCancel"></form-group>
                <form-permission v-else-if="isPermissionForm(currentData)" :action-type="actionType" :current-data="currentData" :tty="tty" :menutree="items"
                           @success="handleSuccess" @cancel="handleCancel"></form-permission>
                <form-menu v-else-if="isMenuForm(currentData)" :action-type="actionType" :current-data="currentData" :tty="tty" :menutree="items"
                           @success="handleSuccess" @cancel="handleCancel"></form-menu>
                <form-app v-else-if="isAppForm(currentData)" :action-type="actionType" :current-data="currentData" :tty="tty" :menutree="items"
                          @success="handleSuccess" @cancel="handleCancel"></form-app>
            </div>
        </div>
    </div>
</template>

<script>
    import { mapState, mapActions } from 'vuex';

    import formGroup from './form-group';
    import formMenu from './form-menu';
    import formApp from './form-app';
    import formPermission from './form-permission';
    import common from '../../../common/common';

    export default {
        props: {
            tty: {
                type: Number,
                default: 1
            },
            appId: Number,
            selectedId: [ Number, String ]
        },
        data() {
            return {
                winName: '新增',
                items: [],
                loading: false,
                currentData: {},
                groups: [],
                contents: [],

                actionType: 'view',     // createGroup | createMenu | edit | view
                form: {},   // _.cloneDeep(DEFAULT_FORM),
                expandedKeys: [],
                // checkedKeys: [],
                treeSetting: {
                    children: 'subs',
                    label: 'name',
                    'icon-class': 'hello-icon'
                },
                queryText: "",

                currentNode: null,
                currentResolve: null,

                // showFormSelectWin: false,
                formSelectWinName: '选择表单',
                nodePopoverShow: false,
                popData: null,
                menuFormWinName: "",
                menuFormShow: false
            }
        },
        components: {
            formGroup,
            formMenu,
            formApp,
            formPermission
        },
        created () {

        },
        mounted () {
            this.init();
        },
        watch: {
            '$route' (to, from) {

            },
            'selectedMenus'(val) {

            },
            appId() {
                this.init();
            },
	    queryText(val) {
                this.$refs.menutree.filter(val);
            },
            tty() {
                this.init();
            },

        },
        filters: {
            viewLabel(view) {
                return (view && view.view_name) || '默认';
            }
        },
        computed: {
            ...mapState([
                'loginUser',
                'project'
            ]),
            canEdit() {
                let editing = true;

                if(this.currentData && this.currentData.project_id == -1) {
                    if(this.loginUser.type == '_SUPER') {
                        editing = true;
                    } else {
                        editing = false;
                    }
                }

                return editing;
            }
        },
        methods: {
            ...common,
            filterNode(value, data) {
                if (!value) return true;
                if(!data.name) return true;
                return data.name.indexOf(value) !== -1;
            },
            async init() {
                let menutree;

                this.loading = true;

                if(this.appId) {
                    let mySub = await this.$japi.menu.getSubMenuTree(this.appId, this.tty);
                    // 只显示子菜单
                    menutree = _.get(mySub, '[0].subs', []);
                } else {
                    menutree = await this.$japi.menu.getMenuTree(this.tty);
                }

                this.items = menutree || [];
                this.currentData = null;
                // 默认展开一级菜单
                this.expandedKeys = _.map(menutree, 'tid');

                this.loading = false;
                this.selectDefaultMenu();
            },
            selectDefaultMenu() {
                if(this.currentData) return;

                let dftId = this.selectedId;
                if(!dftId) {
                    let menu = this.$utils.getTreeDataFn(this.items, nodeData => nodeData && nodeData.content_id > 0, 'subs');
                    dftId = _.get(menu, `tid`);
                }
                if(!dftId) return;

                let data = this.$utils.getTreeData(this.items, 'tid', dftId, 'subs');
                if(data) {
                    this.handleClick(data);
                    this.expandedKeys.push(dftId);
                    this.$refs.menutree.setCurrentKey(dftId);
                }
            },
            close(flag) {
                this.$emit('close', flag);
            },
            empty: function() {},
            async refreshCurrentNode(tid) {
                await this.init();

                if(!tid) {
                    return;
                }
                let paths = this.$utils.getTreePath(tid, this.items, 'tid', 'subs', true);
                let info = _.find(paths, { tid: tid });

                // console.log(tid);
                // console.log(this.items);
                // console.log(_.map(paths, 'tid'));

                this.expandedKeys = _.map(paths, 'tid');
                this.handleClick(info);
            },
            async refreshParentNode(dt) {

                let isMbGroup = this._isGroup(dt);
                let parent_id = null;
                if(isMbGroup) {
                    parent_id = _.get(dt, 'parent_id');
                } else {
                    parent_id = _.get(dt, 'content_group_id');
                }

                // console.log(dt);
                // console.log(parent_id)

                if(!parent_id) return;

                let tid = `g_${parent_id}`;

                this.refreshCurrentNode(tid);
            },
            handleClick(data, node, ele) {
                // this.chooseNode(data);
                this.actionType = 'view';
                this.currentData = data;
                this.form = _.cloneDeep(this.currentData);

                if(this.$refs.menutree.store.nodesMap && this.$refs.menutree.store.nodesMap[ data.tid ]) {
                    this.$refs.menutree.store.nodesMap[ data.tid ].expanded = true;
                }
                this.$emit('select', data);
            },
            handleClearSelect() {
                try {
                    this.$refs.menutree.setCurrentNode({ tid: null });
                } catch(e) {
                    // e.message
                }

                this.currentData = {};
                this.form = {}; // _.clone(DEFAULT_FORM);
            },
            isSelected(data) {
                return this.isGroup(data) || this.isMenu(data) || this.isApp(data) || this.isPermissionMenu(data);
            },
            isGroupForm(currentData) {
                return this.actionType == 'createGroup' || (this._isVE() && this.isGroup(currentData));
                /** && (this.actionType == 'edit' || this.actionType == 'view') **/
            },
            isMenuForm(currentData) {
                return this.actionType == 'createMenu' || (this._isVE() && this.isMenu(currentData));
                /** && (this.actionType == 'edit' || this.actionType == 'view') **/
            },
            isAppForm(currentData) {
                return this.actionType == 'createApp' || (this._isVE() && this.isApp(currentData));
                /**  && (this.actionType == 'edit' || this.actionType == 'view') **/
            },
            isPermissionForm(currentData) {
                return this.actionType == 'createPermission' || (this._isVE() && this.isPermissionMenu(currentData));
            },
            handleShowCreateGroup() {
                this.actionType = 'createGroup';     // createGroup | createMenu | edit | view

                if(!this.isGroup(this.currentData)) {
                    return;
                }
            },
            handleShowCreateApp() {
                this.actionType = 'createApp';     // createGroup | createMenu | edit | view
                this.menuFormShow = true;
                this.menuFormWinName = `新增应用`;
                if(!this.isGroup(this.currentData)) {
                    return;
                }
            },
            handleShowCreateMenu() {
                this.actionType = 'createMenu';
                this.menuFormShow = true;
                this.menuFormWinName = `新增菜单`;
            },
	    handleShowCreateGroupRoot() {
                // this.popData = null;
                this.popData = this.currentData;
                this.handleShowCreateGroup();
            },
            handleShowCreateMenuRoot() {
                // this.popData = null;
                this.popData = this.currentData;
                this.handleShowCreateMenu();
            },
            handleShowCreatePermission() {
                this.actionType = 'createPermission';
            },
            handleShowEdit() {
                if(!this.popData) return;
                let name = this.isMenu(this.popData) ? this.popData.content_name: this.popData.group_name;
                this.actionType = 'edit';
                this.menuFormShow = true;
                this.menuFormWinName = `修改【${name}】`;
            },
            async handleShowDelete(dt) {

                if(!dt) return;

                let isMbGroup = this._isGroup(dt);
                let msg = `确定删除${ isMbGroup ? '分组': '菜单' }【${dt.name}】?`;
                this.$confirm(msg, '删除确认').then(async () => {
                    let id = dt.id;
                    let ret = null;

                    if(isMbGroup) {
                        ret = await this.$japi.group.removeGroup(id);
                    } else {
                        ret = await this.$japi.menu.removeMenu(id);
                    }

                    if(!ret) {
                        return;
                    }

                    let parent_id = null;

                    if(isMbGroup) {
                        parent_id = _.get(dt, 'parent_id');
                    } else {
                        parent_id = _.get(dt, 'content_group_id');
                    }

                    let tid = `g_${parent_id}`;

                    this.refreshCurrentNode(tid);
                    this.handleClearSelect();
                }).catch(e => {

                });
            },
            handleCancelEdit() {
                this.actionType = 'view';
            },
            async handleMenuUp(it) {
                let isGroup = this.isGroup(it);
                let id = it.id;
                let ret = null;

                if(isGroup) {
                    ret = await this.$japi.group.groupMoveUp(id);
                } else {
                    ret = await this.$japi.menu.menuMoveUp(id);
                }
                if(ret) {
                    this.refreshParentNode(it);
                }
            },
            async handleMenuDown(it) {
                let isGroup = this.isGroup(it);
                let id = it.id;
                let ret = null;

                if(isGroup) {
                    ret = await this.$japi.group.groupMoveDown(id);
                } else {
                    ret = await this.$japi.menu.menuMoveDown(id);
                }

                if(ret) {
                    this.refreshParentNode(it);
                }
            },
            handleDragDrop(node, relaNode, relaPos, evt) {
                //
                let cdata = _.get(node, 'data');
                let rdata = _.get(relaNode, 'data');

                let isGroup = this._isGroup(cdata);
                let isRelaGroup = this._isGroup(rdata);
                let relaId = -1;
                let dataId = null;

                if(!cdata) return;

                if(isRelaGroup) {
                    relaId = _.get(rdata, 'group_id');
                } else {
                    relaId = _.get(rdata, 'content_id');
                }

                if(isGroup) {
                    dataId = _.get(cdata, 'group_id');
                    this.$japi.group.changeDir(dataId, relaId, relaPos, isRelaGroup);
                } else {
                    dataId = _.get(cdata, 'content_id');
                    this.$japi.menu.changeDir(dataId, relaId, relaPos, isRelaGroup);
                }
                console.log(node, lastNode, relaPos, evt);
            },
            handleCancel() {
                this.actionType = 'view';
                this.menuFormShow = false;
            },
            handleSuccess(tid) {
                this.refreshCurrentNode(tid);
                this.menuFormShow = false;
            },
            showNodeMorePopover(e, data) {

                let $npop = this.$refs.nodeMorePopover;

                $npop.showPopper = false;
                $npop.doClose();
                $npop.doDestroy(true);

                this.popData = data;
                this.$nextTick(() => {
                    //显示新的
                    $npop.referenceElm = $npop.$refs.reference = e.target;
                    $npop.showPopper = true;
                    $npop.$emit('input', true);
                    $npop.doShow();
                })
            },
            handleEditShow() {
                this.actionType = 'edit';
            },
            handleRemoveShow() {
                this.handleShowDelete(this.popData);
            },
            getNodeName(data) {
                let name = _.get(data, 'name');
                let type = _.get(data, 'content_type');

                if(type === 'PER_FORM') {
                    name = _.get(data, 'form.form_name');
                    let vname = _.get(data, 'view.view_name');

                    if(vname) name += `[${ vname }]`;
                } else if(type === 'PER_REPORT') {
                    name = _.get(data, 'report.title');
                } else if(type === 'PER_API') {
                    name = _.get(data, 'api.api_name');
                }

                return name;
            },
            getNodeIconFont(data) {
                let type = _.get(data, 'content_type');

                if(type === 'PER_FORM') {
                    return "fa fa-foursquare";
                } else if(type === 'PER_REPORT') {
                    return "fa fa-chart-pie"
                } else if(type === 'PER_API') {
                    return "fa fa-node-js"
                } else {
                    return this.getIconFont(data);
                }
            }
        }
    }
</script>

<style lang="scss" scoped>
    .menu-custom-tree {
        padding-top: 5px;
    }
    .menu-custom-tree-node {
        width: 100%;
        position: relative;
        cursor: move;

        .btn-up, .btn-down {
            position: absolute;
            top: 0px;
            right: 5px;
            font-size: 12px;
            background: #DDD;
            color: #999;
            width: 16px;
            height: 16px;
            -webkit-border-radius: 50%;
            -moz-border-radius: 50%;
            border-radius: 50%;
            text-align: center;
            line-height: 16px;
            display: none;

            &:hover {
                color: #333;
                background: #CCC;
            }
        }
        .btn-up {
            right: 24px;
        }

        &:hover {
            .btn-up, .btn-down {
                display: block;
            }
        }
    }
    .mb-wrap .mb-info .info {
        overflow-y: auto;
    }
</style>
